/** @file        bdy_api.h
  * @brief       与百度云服务器交互的接口
  * @details   
  * @author      皓瑞
  * @date        2020-12-28
  * @version     V1.0
  * @copyright   
  **********************************************************************************
  * @attention
  **********************************************************************************
*/

#ifndef BDYAPI_H
#define BDYAPI_H

/* Includes ------------------------------------------------------------------*/
#include <iostream>
#include <exception>
#include "curl/curl.h"
#include "json/json.h"
#include "openssl/crypto.h"
#include "openssl/ssl.h"
#include "baiduyun/base64.h"

/* Exported macro ------------------------------------------------------------*/
#define BDY_API_DEBUG   0

  /**
   * @brief 封装百度云AI相关的接口
   * @note  
   */
namespace BaiDuYun{
  /**
   * @brief 封装百度云人脸识别相关的接口
   * @note  
   */
  class Face{
    public:
      /**
       * @brief 构造函数
       * @param AK 应用的API key
       * @param SK 应用的Secret key
       * @note  禁用默认构造函数，必须提供AK以及SK，用于获取与
       *        服务器协商通信所需的密钥,若失败则抛出异常，不可
       *        恢复，将会结束进程
       */
      Face() = delete;
      Face(const std::string& AK, const std::string &SK):AK_{AK},SK_{SK}{
         /* 全局初始化curl */
         if(curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) 
           throw std::exception();
         /* 初始化curl easy */
         curl = curl_easy_init();
         if(curl == NULL) 
            throw std::exception();
         /* 获取密钥 */
         if(AccessToken(access_token_, AK_, SK_)) 
            throw std::exception();
         /* 初始化人脸库配置 */
         faceSettings_["image_type"]        = "BASE64";
         faceSettings_["max_face_num"]      = 1;
         faceSettings_["match_threshold"]   = 70;
         faceSettings_["quality_control"]   = "LOW";
         faceSettings_["liveness_control"]  = "LOW";
         faceSettings_["max_user_num"]      = 1;
         faceSettings_["group_id_list"]     = "hid000001";
         faceSettings_["group_id"]          = "hid000001";
         faceSettings_["user_id"]           = "test";
         faceSettings_["user_info"]         = "User Info";
         faceSettings_["action_type"]       = "APPEND";
         faceSettings_["face_sort_type"]    = 1;
      }
      /**
       * @brief 析构函数
       */
      ~Face(){
        curl_easy_cleanup(curl);

        curl_global_cleanup();
      }
     /**
      * @brief 一个简单的重载方式用于配置人脸库的设置
      * @param key:需要配置的选项 
      * @note  参数详见百度云人脸API文档定义(不提供合法Value值检查)
      *        https://ai.baidu.com/ai-doc/FACE/7k37c1jfr
      */
      Json::Value& operator[] (const std::string& key);

       /**
       * @brief 获取密钥
       * @note  仅供用户查看
       */     
      const std::string& GetAccessToken(){
        return access_token_;
      }
      
      /**
       * @brief  人脸搜索
       * @param  imageKey:键值对"image"的value,可传入图片的URL或者图像的二进制数据
       *         示image_type而定,默认图像的二进制数据
       * @return true则查找到对应的人脸
       * @note   搜索配置由faceSearchSettings_决定，支持的图像格式为png、jpg、jpeg以及gif
       */
      bool FaceSearch(const std::string& imageKey);
      /**
       * @brief  人脸注册
       * @param  imageKey:键值对"image"的value,可传入图片的URL或者图像的二进制数据
       *         示image_type而定,默认图像的二进制数据
       * @return true成功添加对应的人脸
       * @note   搜索配置由faceSearchSettings_决定，支持的图像格式为png、jpg、jpeg以及gif
       *         人脸注册也需要进行活体检测
       */
      bool FaceAdd(const std::string& imageKey);
      /**
       * @brief  人脸更新
       * @param  imageKey:键值对"image"的value,可传入图片的URL或者图像的二进制数据
       *         示image_type而定,默认图像的二进制数据
       * @return true成功添加对应的人脸
       * @note   搜索配置由faceSearchSettings_决定，支持的图像格式为png、jpg、jpeg以及gif
       *         人脸更新也需要进行活体检测
       */
      bool FaceUpdate(const std::string& imageKey);
      std::string  curErrorMsg{""};                           //< 存放错误信息
    private:
      std::string AK_;
      std::string SK_;
      CURL *curl{nullptr};                                     //< 建立easy curl句柄  
      std::string access_token_;                               //< 存放密钥
      std::string jsonResult_;                                 //< 存放json的返回值
      Json::Value faceSettings_;                               //< 默认人脸库的配置
      static const std::string access_token_url_;              //< 访问百度云密钥的URL
      static const std::string face_request_url_;              //< 访问百度云人脸API的URL
      int AccessToken(std::string &access_token, const std::string &AK, const std::string &SK); 
    protected:
  };

}



#ifdef  __cplusplus
extern "C" {
#endif

/* Exported types ------------------------------------------------------------*/

/* Exported functions --------------------------------------------------------*/  

#ifdef  __cplusplus
}
#endif


#endif /* BDYAPI_H */

/*****************************END OF FILE*****************************/